#include "matrix.h"
#include "thread.h"

/* default pstate of thread, DAIF not mask (means that the interrupt is enable) */
#define DEFAULT_PSTATE  0x00000005U

mx_void_pt mx_thread_stack_init (mx_void_pt stack, mx_usize_t size, mx_thread_entry_t entry,
                                 mx_thread_boot_t boot, mx_thread_pt thread)
{
    mx_void_pt stacktop = (mx_void_pt)((mx_usize_t)stack + size - 16);
    mx_uint64_pt sp = (mx_uint64_pt)stacktop;

    *(sp--) = (mx_uint64_t)thread;          // X0
    *(sp--) = (mx_uint64_t)1;               // X1
    *(sp--) = (mx_uint64_t)2;               // X2
    *(sp--) = (mx_uint64_t)3;               // X3
    *(sp--) = (mx_uint64_t)4;               // X4
    *(sp--) = (mx_uint64_t)5;               // X5
    *(sp--) = (mx_uint64_t)6;               // X6
    *(sp--) = (mx_uint64_t)7;               // X7
    *(sp--) = (mx_uint64_t)8;               // X8
    *(sp--) = (mx_uint64_t)9;               // X9
    *(sp--) = (mx_uint64_t)10;              // X10
    *(sp--) = (mx_uint64_t)11;              // X11
    *(sp--) = (mx_uint64_t)12;              // X12
    *(sp--) = (mx_uint64_t)13;              // X13
    *(sp--) = (mx_uint64_t)14;              // X14
    *(sp--) = (mx_uint64_t)15;              // X15
    *(sp--) = (mx_uint64_t)16;              // X16
    *(sp--) = (mx_uint64_t)17;              // X17
    *(sp--) = (mx_uint64_t)18;              // X18
    *(sp--) = (mx_uint64_t)19;              // X19
    *(sp--) = (mx_uint64_t)20;              // X20
    *(sp--) = (mx_uint64_t)21;              // X21
    *(sp--) = (mx_uint64_t)22;              // X22
    *(sp--) = (mx_uint64_t)23;              // X23
    *(sp--) = (mx_uint64_t)24;              // X24
    *(sp--) = (mx_uint64_t)25;              // X25
    *(sp--) = (mx_uint64_t)26;              // X26
    *(sp--) = (mx_uint64_t)27;              // X27
    *(sp--) = (mx_uint64_t)28;              // X28
    *(sp--) = (mx_uint64_t)29;              // X29  FP
    *(sp--) = (mx_uint64_t)30;              // X30  LR
    *(sp--) = (mx_uint64_t)(sp - 2);        // X31  SP
    *(sp--) = (mx_uint64_t)DEFAULT_PSTATE;  // PSTATE
    *(sp--) = (mx_uint64_t)boot;            // break-point

    return stacktop;
}
